package cn.zl.ssoserver.login.controller;

import cn.zl.ssoserver.constant.ServerConstant;
import cn.zl.ssoserver.login.service.LoginService;
import cn.zl.ssoserver.util.SsoCookieUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Description:登录控制器
 * @Author: zllwsy
 * @Date: 2020/11/4 11:02
 */
@Controller
public class LoginController {
    private final RedisTemplate<String, String> redisTemplate;
    private final LoginService loginService;

    @Autowired
    public LoginController(RedisTemplate<String, String> redisTemplate,LoginService loginService) {
        this.redisTemplate = redisTemplate;
        this.loginService = loginService;
    }

    /**
     * 登录页面
     * @param originalUrl  源url
     * @param uuid  客户端唯一标识
     * @param response
     * @return
     */
    @RequestMapping("/loginPage")
    public String loginPage(String originalUrl, String uuid, HttpServletResponse response) {
        SsoCookieUtil.setCookie(response, "originalUrl", originalUrl, ServerConstant.REDIS_TICKET_ALIVE_SECONDS);
        SsoCookieUtil.setCookie(response, "uuid", uuid, ServerConstant.REDIS_TICKET_ALIVE_SECONDS);
        return "login";
    }

    /**
     * 登录验证
     * @param userName
     * @param password
     * @param request
     * @param response
     * @return
     */
    @ResponseBody
    @RequestMapping("/login")
    public boolean login(String userName, String password, HttpServletRequest request,HttpServletResponse response){
        boolean loginSuccess = loginService.login(userName, password);
        if (loginSuccess){
            //获取客户端唯一标识
            String uuid = SsoCookieUtil.getCookie(request, "uuid");
            //创建ticket
            String ticket = loginService.createTicket(uuid);
            //存入redis，测试180秒过期
            redisTemplate.opsForValue().set(ServerConstant.REDIS_TICKET_PREFIX + ticket,userName,ServerConstant.REDIS_TICKET_ALIVE_SECONDS, TimeUnit.SECONDS);
            //回源url
            String originalUrl = SsoCookieUtil.getCookie(request,"originalUrl") + "?ticket=" + ticket;
            try {
                //重定向到源url
                response.sendRedirect(originalUrl);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return loginSuccess;
    }

    /**
     * 校验ticket
     * @param ticket
     * @param uuid
     * @return
     */
    @ResponseBody
    @RequestMapping("/checkTicket")
    public String checkTicket(String ticket,String uuid){
        String oldTicketValue = redisTemplate.opsForValue().get(ServerConstant.REDIS_TICKET_PREFIX + ticket);
        //较验ticket
            //当redis存在ticket时验证成功
            if (ticket != null && oldTicketValue != null) {
                //注意：开启一次性ticket验证时，uuid和ticket必传
                if (ServerConstant.ENABLE_DISPOSABLE_TICKET) {
                    //清除旧的ticket
                    redisTemplate.delete(ServerConstant.REDIS_TICKET_PREFIX + ticket);
                    //生成新的ticket
                    String newTicket = loginService.createTicket(uuid);
                    //保存新的ticket
                    redisTemplate.opsForValue().set(ServerConstant.REDIS_TICKET_PREFIX + newTicket, oldTicketValue, ServerConstant.REDIS_TICKET_ALIVE_SECONDS, TimeUnit.SECONDS);
                    //返回新ticket
                    return newTicket;
                } else {
                    return ticket;
                }
            } else return null;
    }

    /**
     * 获取用户信息
     * @param ticket
     * @return
     */
    @ResponseBody
    @RequestMapping("/getUserInfo")
    public Map<String, String> getUserInfo(String ticket) {
        //模拟根据ticket获取用户用户名,根据用户名获取用户信息
        String userName = redisTemplate.opsForValue().get(ServerConstant.REDIS_TICKET_PREFIX + ticket);
        if (StringUtils.isEmpty(userName)) {
            return null;
        }
        Map<String, String> userInfo = new HashMap<>();
        userInfo.put("userName", userName);
        userInfo.put("ticket", ticket);
        return userInfo;
    }
    /**
     * 登出
     * @param ticket
     * @return
     */
    @ResponseBody
    @RequestMapping("/logout")
    @SuppressWarnings("all")
    public boolean logout(String ticket){
        return redisTemplate.delete(ServerConstant.REDIS_TICKET_PREFIX+ticket);
    }
}
